﻿using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;

namespace Dsl.Ped.Controls.ProjectiveControl.Helpers
{
    /// <summary>
    /// Helper of the events
    /// </summary>
    public static class EventHelper
    {
        /// <summary>
        /// Get the full name of the owner
        /// </summary>
        /// <param name="fullEventName">Full name of the event (including the full class name and event name)</param>
        /// <returns>Full name of the event owner</returns>
        public static string GetOwnerTypeName(string fullEventName)
        {
            if (string.IsNullOrEmpty(fullEventName)) return string.Empty;

            Regex regex = new Regex(@"(?<classname>.*)\.(?<eventname>.*)");
            Match match = regex.Match(fullEventName);

            if (match.Success)
            {
                return match.Groups["classname"].Value;
            }

            return string.Empty;
        }

        /// <summary>
        /// Get short name of the event from the full Event name
        /// </summary>
        /// <param name="fullEventName">Full name of the event (including the full class name and event name)</param>
        /// <returns>Short event name</returns>
        public static string GetEventName(string fullEventName)
        {
            if (string.IsNullOrEmpty(fullEventName)) return string.Empty;

            Regex regex = new Regex(@"(?<classname>.*)\.(?<eventname>.*)");
            Match match = regex.Match(fullEventName);

            if (match.Success)
            {
                return match.Groups["eventname"].Value;
            }

            return fullEventName;
        }

        public static EventInfo GetEventInfoByEventName(object sender, string eventName)
        {
            string ownerTypeName = EventHelper.GetOwnerTypeName(eventName);
            string shortEventName = EventHelper.GetEventName(eventName);

            if (string.IsNullOrEmpty(eventName))
            {
                return null;
            }

            if (string.IsNullOrEmpty(ownerTypeName))
            {
                var info = sender.GetType().GetEvent(shortEventName);
                if (info == null)
                {
                    throw new ArgumentException(string.Format("Event '{0}' doesn't exist", shortEventName));
                }
                return info;
            } else
            {
                var type = TypeHelper.GetType(ownerTypeName) ??
                           TypeHelper.GetType("System.Windows.Controls." + ownerTypeName);

                if (type == null)
                {
                    throw new Exception(string.Format("Class '{0}' can not be found", ownerTypeName));
                }

                var info = type.GetEvent(shortEventName);
                if (info == null)
                {
                    throw new ArgumentException(string.Format("Event '{0}' doesn't exist", shortEventName));
                }
                return info;
            }
        }

        public static RoutedEvent GetEventByEventInfo(EventInfo eventInfo)
        {
            var eventOwner = (eventInfo.DeclaringType == null) ? string.Empty : eventInfo.DeclaringType.Name;
            var eventName = eventInfo.Name;

            var routedEvents = EventManager.GetRoutedEvents();
            return routedEvents.Where(routedEvent => routedEvent.OwnerType.Name.Equals(eventOwner)).FirstOrDefault(re => re.Name.Equals(eventName));
        }
    }
}
